#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#include "queue.h"

/**
 * @brief 初始化队列为空
 *
 * @param pq 插入队列指针
 * @return true
 * @return false
 */
void InitializeQueue(CirQueue *pq)
{
    pq->base = (ElemType *)malloc(MAXSIZE * sizeof(ElemType));
    pq->front = 0;
    pq->rear = 0;
}

/**
 * @brief 确定队列为空
 *
 * @param pq 插入队列指针
 * @return true
 * @return false
 */
bool QueueIsEmpty(const CirQueue *pq)
{
    if (pq->front - pq->rear == 0)
        return true;
    else
        return false;
}

/**
 * @brief 确定队列为满
 *
 * @param pq 插入队列指针
 * @return true
 * @return false
 */
bool QueueIsFull(const CirQueue *pq){
    return (pq->rear + 1) % MAXSIZE == pq->front;
}

/**
 * @brief 得到队列的项数
 *
 * @param pq 插入队列指针
 * @return unsigned int 返回队列的项数
 */
unsigned int QueueItemCount(const CirQueue *pq)
{
    return (pq->rear - pq->front + MAXSIZE) % MAXSIZE;
}

/**
 * @brief 添加队列尾部添加项
 *
 * @param item
 * @param pq 插入队列指针
 * @return true
 * @return false
 */
bool AddItemFromTail(ElemType item, CirQueue *pq){
    if (QueueIsFull(pq))
    {
        fprintf(stderr, "QueueIsFull !\n");
        return false;
    }
    pq->base[pq->rear] = &item;
    
}

/**
 * @brief Get the Top object
 *
 * @param elem
 * @param pq
 * @return true
 * @return false
 */
bool getTop(ElemType *elem, CirQueue *pq)
{
    if (QueueIsEmpty(pq))
    {
        fprintf(stderr, "QueueIsEmpty !\n");
        return false;
    }
    else
    {
        *elem = pq->base[pq->front];
        return true;
    }
}

/**
 * @brief 从队列开头删除项
 *
 * @param pitem item指针,通常新建一个空指针传入,队列中待删除的项存储在pitem中指向的位置
 * @param pq 插入队列指针
 * @return true
 * @return false
 */
bool DeleteItemFromTail(ElemType *pitem, CirQueue *pq)
{

    if (QueueIsEmpty(pq))
    {
        fprintf(stderr, "QueueIsEmpty !\n");
        return false;
    }
    else
    {
        *pitem = pq->base[pq->front];   // get object
        

    }
}

/**
 * @brief 清空队列
 *
 * @param pq
 * @return true
 * @return false
 */
bool EmptyQueue(CirQueue *pq){
    if (QueueIsEmpty(pq))
    {
        fprintf(stderr, "QueueIsEmpty !\n");
        return false;
    }else{
        // TODO:
        return true;
    }
    
}

static void frontMove(CirQueue *pq){
    pq->front = ((pq->front + 1) % MAXSIZE);
}

static void rearMove(CirQueue *pq){
    pq->rear = ((pq->rear + 1) % MAXSIZE);
}